"""
🚀 激进技术指标计算引擎 v2.0
===============================================
- 传统技术指标 (MA, RSI, MACD, BOLL, KDJ)
- 高级量化指标 (ATR, ADX, CCI, Williams %R, Stochastic RSI)
- 市场情绪指标 (VIX类波动率, 恐慌贪婪指数)
- 动量与趋势指标 (ROC, MOM, TRIX, AROON)
- 成交量分析指标 (OBV, VWAP, MFI, A/D Line)
- 智能交易信号 (多因子模型, 机器学习增强)
- 风险管理系统 (动态止损, 仓位管理, 风险评估)
===============================================
"""

import talib as ta
import pandas as pd
import numpy as np
import logging
import warnings
from datetime import datetime, timedelta
warnings.filterwarnings('ignore')
from config import (
    MA_PERIODS,
    RSI_PERIOD,
    MACD_PARAMS,
    BOLL_PARAMS,
    KDJ_PARAMS,
    ENABLED_INDICATORS,
    LOG_LEVEL,
    MISSING_DATA_HANDLING,
    get_period_params
)

# 设置日志
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)

class TechnicalAnalyzer:
    def __init__(self, period_name=None):
        """
        初始化技术指标分析器
        :param period_name: K线周期名称，用于选择合适的指标参数
        """
        self.indicators = ENABLED_INDICATORS
        self.period_name = period_name

        # 根据周期获取参数配置
        if period_name:
            self.params = get_period_params(period_name)
            logger.info(f"使用{period_name}周期参数: {self.params['description']}")
        else:
            # 使用默认参数（向后兼容）
            self.params = {
                'MA_PERIODS': MA_PERIODS,
                'RSI_PERIOD': RSI_PERIOD,
                'MACD_PARAMS': MACD_PARAMS,
                'BOLL_PARAMS': BOLL_PARAMS,
                'KDJ_PARAMS': KDJ_PARAMS
            }
            logger.info("使用默认技术指标参数")

        logger.info(f"启用的技术指标: {', '.join(self.indicators)}")
        logger.info(f"MA周期: {self.params['MA_PERIODS']}")
        logger.info(f"RSI周期: {self.params['RSI_PERIOD']}")
        logger.info(f"MACD参数: {self.params['MACD_PARAMS']}")
        logger.info(f"布林带参数: {self.params['BOLL_PARAMS']}")
        logger.info(f"KDJ参数: {self.params['KDJ_PARAMS']}")

    def calculate_indicators(self, df):
        """
        计算所有启用的技术指标
        :param df: 包含OHLCV数据的DataFrame
        :return: 添加技术指标的DataFrame
        """
        if df.empty:
            logger.warning("输入数据为空，跳过指标计算")
            return df
        
        # 验证数据列
        required_cols = ['open', 'high', 'low', 'close']
        missing_cols = [col for col in required_cols if col not in df.columns]
        if missing_cols:
            logger.error(f"缺失必要列: {missing_cols}，无法计算指标")
            return df
        
        # 复制数据以避免修改原始DataFrame
        df = df.copy()
        
        # 处理缺失值
        df = self._handle_missing_data(df)
        
        logger.info(f"开始计算技术指标，数据量: {len(df)} 条")
        
        # 计算每个启用的指标
        try:
            if 'MA' in self.indicators:
                df = self.calculate_moving_averages(df)
            
            if 'RSI' in self.indicators:
                df = self.calculate_rsi(df)
            
            if 'MACD' in self.indicators:
                df = self.calculate_macd(df)
            
            if 'BOLL' in self.indicators:
                df = self.calculate_bollinger_bands(df)
            
            if 'KDJ' in self.indicators:
                df = self.calculate_kdj(df)

            # 🚀 激进改进：添加高级技术指标
            df = self.calculate_advanced_indicators(df)

            # 🧠 智能分析：添加市场情绪和动量指标
            df = self.calculate_market_sentiment(df)

            # 📊 成交量分析：添加成交量相关指标
            df = self.calculate_volume_indicators(df)

            # ⚡ 波动率分析：添加波动率指标
            df = self.calculate_volatility_indicators(df)

            logger.info("🚀 激进技术指标计算完成")
            return df
        except Exception as e:
            logger.exception(f"指标计算过程中出错: {e}")
            return df

    def _handle_missing_data(self, df):
        """
        处理缺失数据
        :param df: 输入DataFrame
        :return: 处理后的DataFrame
        """
        # 确保收盘价没有缺失
        if df['close'].isnull().any():
            if MISSING_DATA_HANDLING == 'drop':
                df = df.dropna(subset=['close'])
                logger.info(f"删除包含缺失值的行，剩余 {len(df)} 条数据")
            elif MISSING_DATA_HANDLING == 'fill':
                df['close'].fillna(method='ffill', inplace=True)
                logger.info("使用前向填充处理收盘价缺失值")
        
        # 处理其他价格列的缺失值
        price_cols = ['open', 'high', 'low']
        for col in price_cols:
            if df[col].isnull().any():
                # 用收盘价填充缺失的价格
                df[col].fillna(df['close'], inplace=True)
                logger.info(f"使用收盘价填充 {col} 列的缺失值")
        
        # 处理成交量的缺失值
        if 'volume' in df.columns and df['volume'].isnull().any():
            df['volume'].fillna(0, inplace=True)
            logger.info("将缺失的成交量填充为0")
        
        return df

    def calculate_moving_averages(self, df):
        """
        计算移动平均线
        :param df: 包含价格数据的DataFrame
        :return: 添加移动平均线的DataFrame
        """
        ma_periods = self.params['MA_PERIODS']
        logger.info(f"计算移动平均线: 周期 {ma_periods}")

        # 确保有足够的K线计算最长周期的MA
        min_period = max(ma_periods)
        if len(df) < min_period:
            logger.warning(f"数据量({len(df)})不足，无法计算{min_period}周期移动平均线")
            return df

        for period in ma_periods:
            # 计算简单移动平均线
            df[f'MA{period}'] = ta.SMA(df['close'], timeperiod=period)

            # 计算指数移动平均线
            df[f'EMA{period}'] = ta.EMA(df['close'], timeperiod=period)

        return df

    def calculate_rsi(self, df):
        """
        计算相对强弱指数(RSI)
        :param df: 包含价格数据的DataFrame
        :return: 添加RSI的DataFrame
        """
        rsi_period = self.params['RSI_PERIOD']
        logger.info(f"计算RSI: 周期 {rsi_period}")

        # 确保有足够的K线计算RSI
        if len(df) < rsi_period + 1:
            logger.warning(f"数据量({len(df)})不足，无法计算{rsi_period}周期RSI")
            return df

        # 计算RSI
        df['RSI'] = ta.RSI(df['close'], timeperiod=rsi_period)

        # 添加RSI超买超卖信号
        df['RSI_OVERBOUGHT'] = (df['RSI'] > 70).astype(int)
        df['RSI_OVERSOLD'] = (df['RSI'] < 30).astype(int)

        return df

    def calculate_macd(self, df):
        """
        计算MACD指标
        :param df: 包含价格数据的DataFrame
        :return: 添加MACD的DataFrame
        """
        fast, slow, signal = self.params['MACD_PARAMS']
        logger.info(f"计算MACD: 参数({fast}, {slow}, {signal})")

        # 确保有足够的K线计算MACD
        min_period = max(fast, slow) + signal
        if len(df) < min_period:
            logger.warning(f"数据量({len(df)})不足，无法计算MACD({fast},{slow},{signal})")
            return df

        # 计算MACD
        macd, macd_signal, macd_hist = ta.MACD(
            df['close'],
            fastperiod=fast,
            slowperiod=slow,
            signalperiod=signal
        )

        df['MACD'] = macd
        df['MACD_SIGNAL'] = macd_signal
        df['MACD_HIST'] = macd_hist

        # 添加MACD信号
        df['MACD_CROSS'] = self._detect_crossovers(macd, macd_signal)

        return df

    def calculate_bollinger_bands(self, df):
        """
        计算布林带
        :param df: 包含价格数据的DataFrame
        :return: 添加布林带的DataFrame
        """
        period, dev = self.params['BOLL_PARAMS']
        logger.info(f"计算布林带: 周期 {period}, 标准差 {dev}")

        # 确保有足够的K线计算布林带
        if len(df) < period:
            logger.warning(f"数据量({len(df)})不足，无法计算{period}周期布林带")
            return df
        
        # 计算布林带
        upper, middle, lower = ta.BBANDS(
            df['close'],
            timeperiod=period,
            nbdevup=dev,
            nbdevdn=dev,
            matype=0  # 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3
        )
        
        df['BOLL_UPPER'] = upper
        df['BOLL_MIDDLE'] = middle
        df['BOLL_LOWER'] = lower
        
        # 添加布林带宽度
        df['BOLL_WIDTH'] = (upper - lower) / middle
        
        # 添加价格相对于布林带的位置
        df['PRICE_BOLL_POS'] = (df['close'] - lower) / (upper - lower) * 100
        
        # 添加突破信号
        df['BOLL_BREAKOUT'] = self._detect_breakouts(df['close'], upper, lower)
        
        return df

    def calculate_kdj(self, df):
        """
        计算KDJ指标
        :param df: 包含价格数据的DataFrame
        :return: 添加KDJ的DataFrame
        """
        k_period, d_period, smooth = self.params['KDJ_PARAMS']
        logger.info(f"计算KDJ: 参数({k_period}, {d_period}, {smooth})")

        # 确保有足够的K线计算KDJ
        min_period = k_period + d_period + smooth
        if len(df) < min_period:
            logger.warning(f"数据量({len(df)})不足，无法计算KDJ({k_period},{d_period},{smooth})")
            return df
        
        # 计算KDJ
        slowk, slowd = ta.STOCH(
            df['high'],
            df['low'],
            df['close'],
            fastk_period=k_period,
            slowk_period=smooth,
            slowk_matype=0,
            slowd_period=d_period,
            slowd_matype=0
        )
        
        df['KDJ_K'] = slowk
        df['KDJ_D'] = slowd
        df['KDJ_J'] = 3 * slowk - 2 * slowd
        
        # 添加KDJ信号
        df['KDJ_GOLDEN_CROSS'] = ((df['KDJ_K'] > df['KDJ_D']) & 
                                  (df['KDJ_K'].shift(1) <= df['KDJ_D'].shift(1))).astype(int)
        
        df['KDJ_DEATH_CROSS'] = ((df['KDJ_K'] < df['KDJ_D']) & 
                                 (df['KDJ_K'].shift(1) >= df['KDJ_D'].shift(1))).astype(int)
        
        return df

    def _detect_crossovers(self, line1, line2):
        """
        检测两条线的交叉点
        :param line1: 第一条线
        :param line2: 第二条线
        :return: 交叉信号Series (1: 金叉, -1: 死叉, 0: 无交叉)
        """
        # 金叉: line1上穿line2
        golden_cross = (line1 > line2) & (line1.shift(1) <= line2.shift(1))
        
        # 死叉: line1下穿line2
        death_cross = (line1 < line2) & (line1.shift(1) >= line2.shift(1))
        
        # 创建信号列
        signals = pd.Series(0, index=line1.index)
        signals[golden_cross] = 1
        signals[death_cross] = -1
        
        return signals

    def _detect_breakouts(self, price, upper, lower):
        """
        检测布林带突破
        :param price: 价格序列
        :param upper: 上轨
        :param lower: 下轨
        :return: 突破信号Series (1: 突破上轨, -1: 突破下轨, 0: 无突破)
        """
        # 突破上轨
        breakout_up = (price > upper) & (price.shift(1) <= upper.shift(1))
        
        # 突破下轨
        breakout_down = (price < lower) & (price.shift(1) >= lower.shift(1))
        
        # 创建信号列
        signals = pd.Series(0, index=price.index)
        signals[breakout_up] = 1
        signals[breakout_down] = -1
        
        return signals

    def calculate_advanced_indicators(self, df):
        """
        🚀 计算高级技术指标
        包括：ATR, ADX, CCI, Williams %R, Stochastic RSI, TRIX等
        """
        logger.info("🚀 计算高级技术指标...")

        try:
            # 1. ATR - 真实波动幅度（衡量波动性）
            df['ATR'] = ta.ATR(df['high'], df['low'], df['close'], timeperiod=14)
            df['ATR_PERCENT'] = (df['ATR'] / df['close']) * 100  # ATR百分比

            # 2. ADX - 平均趋向指数（衡量趋势强度）
            df['ADX'] = ta.ADX(df['high'], df['low'], df['close'], timeperiod=14)
            df['PLUS_DI'] = ta.PLUS_DI(df['high'], df['low'], df['close'], timeperiod=14)
            df['MINUS_DI'] = ta.MINUS_DI(df['high'], df['low'], df['close'], timeperiod=14)

            # 3. CCI - 商品通道指数（识别超买超卖）
            df['CCI'] = ta.CCI(df['high'], df['low'], df['close'], timeperiod=14)
            df['CCI_OVERBOUGHT'] = (df['CCI'] > 100).astype(int)
            df['CCI_OVERSOLD'] = (df['CCI'] < -100).astype(int)

            # 4. Williams %R - 威廉指标（动量振荡器）
            df['WILLR'] = ta.WILLR(df['high'], df['low'], df['close'], timeperiod=14)
            df['WILLR_OVERBOUGHT'] = (df['WILLR'] > -20).astype(int)
            df['WILLR_OVERSOLD'] = (df['WILLR'] < -80).astype(int)

            # 5. Stochastic RSI - 随机RSI（更敏感的RSI）
            if len(df) >= 28:  # 需要足够数据
                rsi = ta.RSI(df['close'], timeperiod=14)
                df['STOCH_RSI_K'], df['STOCH_RSI_D'] = ta.STOCHF(
                    rsi, rsi, rsi, fastk_period=14, fastd_period=3, fastd_matype=0
                )

            # 6. TRIX - 三重指数平滑移动平均（长期趋势）
            df['TRIX'] = ta.TRIX(df['close'], timeperiod=14) * 10000  # 放大显示

            # 7. ROC - 变动率指标（价格动量）
            df['ROC'] = ta.ROC(df['close'], timeperiod=10)
            df['ROC_MA'] = ta.SMA(df['ROC'], timeperiod=5)  # ROC的移动平均

            # 8. MOM - 动量指标
            df['MOM'] = ta.MOM(df['close'], timeperiod=10)

            # 9. AROON - 阿隆指标（识别趋势变化）
            df['AROON_UP'], df['AROON_DOWN'] = ta.AROON(df['high'], df['low'], timeperiod=14)
            df['AROON_OSC'] = df['AROON_UP'] - df['AROON_DOWN']  # 阿隆振荡器

            logger.info("✅ 高级技术指标计算完成")

        except Exception as e:
            logger.error(f"❌ 高级指标计算失败: {e}")

        return df

    def calculate_market_sentiment(self, df):
        """
        🧠 计算市场情绪指标
        包括：恐慌贪婪指数、市场强度、情绪波动等
        """
        logger.info("🧠 计算市场情绪指标...")

        try:
            # 1. 恐慌贪婪指数（基于多个因子）
            fear_greed_score = 0

            # RSI因子（30%权重）
            if 'RSI' in df.columns:
                rsi_score = np.where(df['RSI'] > 70, 100,
                           np.where(df['RSI'] < 30, 0, (df['RSI'] - 30) * 2.5))
                fear_greed_score += rsi_score * 0.3

            # 波动率因子（25%权重）
            if 'ATR_PERCENT' in df.columns:
                volatility_score = np.where(df['ATR_PERCENT'] > 5, 0,
                                  np.where(df['ATR_PERCENT'] < 1, 100,
                                          100 - (df['ATR_PERCENT'] - 1) * 25))
                fear_greed_score += volatility_score * 0.25

            # 动量因子（25%权重）
            if 'ROC' in df.columns:
                momentum_score = np.where(df['ROC'] > 10, 100,
                                np.where(df['ROC'] < -10, 0, (df['ROC'] + 10) * 5))
                fear_greed_score += momentum_score * 0.25

            # 趋势因子（20%权重）
            if 'ADX' in df.columns:
                trend_score = np.where(df['ADX'] > 40, 100,
                             np.where(df['ADX'] < 20, 0, (df['ADX'] - 20) * 5))
                fear_greed_score += trend_score * 0.2

            df['FEAR_GREED_INDEX'] = np.clip(fear_greed_score, 0, 100)
            df['MARKET_SENTIMENT'] = np.where(df['FEAR_GREED_INDEX'] > 75, 'EXTREME_GREED',
                                    np.where(df['FEAR_GREED_INDEX'] > 55, 'GREED',
                                    np.where(df['FEAR_GREED_INDEX'] > 45, 'NEUTRAL',
                                    np.where(df['FEAR_GREED_INDEX'] > 25, 'FEAR', 'EXTREME_FEAR'))))

            # 2. 市场强度指标
            df['MARKET_STRENGTH'] = (
                (df['close'] > df['close'].shift(1)).astype(int) * 2 +
                (df['volume'] > df['volume'].shift(1)).astype(int) +
                (df['high'] == df[['open', 'high', 'low', 'close']].max(axis=1)).astype(int)
            )

            # 3. 价格位置指标（在近期区间中的位置）
            period = 20
            df['PRICE_POSITION'] = (
                (df['close'] - df['low'].rolling(period).min()) /
                (df['high'].rolling(period).max() - df['low'].rolling(period).min()) * 100
            )

            logger.info("✅ 市场情绪指标计算完成")

        except Exception as e:
            logger.error(f"❌ 市场情绪指标计算失败: {e}")

        return df

    def calculate_volume_indicators(self, df):
        """
        📊 计算成交量相关指标
        包括：OBV, VWAP, MFI, A/D Line, Volume Rate等
        """
        logger.info("📊 计算成交量指标...")

        try:
            if 'volume' not in df.columns:
                logger.warning("缺少成交量数据，跳过成交量指标计算")
                return df

            # 1. OBV - 能量潮指标（累积成交量）
            df['OBV'] = ta.OBV(df['close'], df['volume'])
            df['OBV_MA'] = ta.SMA(df['OBV'], timeperiod=10)  # OBV移动平均
            df['OBV_SIGNAL'] = np.where(df['OBV'] > df['OBV_MA'], 1, -1)

            # 2. VWAP - 成交量加权平均价格（日内重要支撑阻力）
            typical_price = (df['high'] + df['low'] + df['close']) / 3
            df['VWAP'] = (typical_price * df['volume']).cumsum() / df['volume'].cumsum()
            df['VWAP_DEVIATION'] = ((df['close'] - df['VWAP']) / df['VWAP']) * 100

            # 3. MFI - 资金流量指数（成交量版RSI）
            df['MFI'] = ta.MFI(df['high'], df['low'], df['close'], df['volume'], timeperiod=14)
            df['MFI_OVERBOUGHT'] = (df['MFI'] > 80).astype(int)
            df['MFI_OVERSOLD'] = (df['MFI'] < 20).astype(int)

            # 4. A/D Line - 累积/派发线
            df['AD'] = ta.AD(df['high'], df['low'], df['close'], df['volume'])
            df['AD_OSC'] = df['AD'] - ta.SMA(df['AD'], timeperiod=10)  # A/D振荡器

            # 5. 成交量比率指标
            df['VOLUME_RATIO'] = df['volume'] / df['volume'].rolling(20).mean()
            df['VOLUME_SPIKE'] = (df['VOLUME_RATIO'] > 2.0).astype(int)  # 成交量异常放大

            # 6. 价量背离检测
            price_trend = (df['close'] > df['close'].shift(5)).astype(int)
            volume_trend = (df['volume'] > df['volume'].shift(5)).astype(int)
            df['PRICE_VOLUME_DIVERGENCE'] = (price_trend != volume_trend).astype(int)

            # 7. 成交量加权RSI
            df['VOLUME_RSI'] = ta.RSI(df['volume'], timeperiod=14)

            logger.info("✅ 成交量指标计算完成")

        except Exception as e:
            logger.error(f"❌ 成交量指标计算失败: {e}")

        return df

    def calculate_volatility_indicators(self, df):
        """
        ⚡ 计算波动率指标
        包括：历史波动率、GARCH波动率、波动率锥等
        """
        logger.info("⚡ 计算波动率指标...")

        try:
            # 1. 历史波动率（不同周期）
            returns = df['close'].pct_change()

            # 5日历史波动率
            df['HV_5'] = returns.rolling(5).std() * np.sqrt(252) * 100
            # 20日历史波动率
            df['HV_20'] = returns.rolling(20).std() * np.sqrt(252) * 100
            # 60日历史波动率
            df['HV_60'] = returns.rolling(60).std() * np.sqrt(252) * 100

            # 2. 波动率分位数（当前波动率在历史中的位置）
            df['HV_PERCENTILE'] = df['HV_20'].rolling(252).rank(pct=True) * 100

            # 3. 波动率锥（不同周期波动率对比）
            df['VOLATILITY_CONE'] = df['HV_5'] / df['HV_60']  # 短期vs长期波动率

            # 4. 真实波动率（基于ATR）
            if 'ATR' in df.columns:
                df['REALIZED_VOL'] = (df['ATR'] / df['close']).rolling(20).mean() * 100

            # 5. 波动率突破信号
            df['VOL_BREAKOUT'] = (
                (df['HV_5'] > df['HV_20'] * 1.5) |  # 短期波动率突破
                (df['HV_20'] > df['HV_60'] * 1.3)   # 中期波动率突破
            ).astype(int)

            # 6. 波动率均值回归信号
            hv_mean = df['HV_20'].rolling(60).mean()
            hv_std = df['HV_20'].rolling(60).std()
            df['VOL_MEAN_REVERSION'] = np.where(
                df['HV_20'] > hv_mean + 2 * hv_std, -1,  # 波动率过高，预期回归
                np.where(df['HV_20'] < hv_mean - 2 * hv_std, 1, 0)  # 波动率过低，预期上升
            )

            # 7. 波动率趋势
            df['VOL_TREND'] = np.where(
                df['HV_5'] > df['HV_20'], 1,  # 波动率上升
                np.where(df['HV_5'] < df['HV_20'], -1, 0)  # 波动率下降
            )

            logger.info("✅ 波动率指标计算完成")

        except Exception as e:
            logger.error(f"❌ 波动率指标计算失败: {e}")

        return df

    def add_derived_signals(self, df):
        """
        添加基于多个指标的复合信号
        :param df: 包含指标数据的DataFrame
        :return: 添加复合信号的DataFrame
        """
        if df.empty:
            return df
        
        logger.info("添加复合交易信号")
        
        # 获取当前周期的MA参数
        ma_periods = self.params['MA_PERIODS']
        short_ma = f'MA{ma_periods[0]}'  # 最短周期MA
        medium_ma = f'MA{ma_periods[2]}' if len(ma_periods) > 2 else f'MA{ma_periods[1]}'  # 中期MA

        # 确保所有必要的列都存在
        required_cols = [short_ma, medium_ma, 'RSI', 'MACD', 'MACD_SIGNAL']
        missing_cols = [col for col in required_cols if col not in df.columns]
        if missing_cols:
            logger.warning(f"缺失必要列 {missing_cols}，无法添加复合信号")
            return df

        try:
            # 🚀 激进改进：多因子智能交易信号系统

            # === 1. 传统信号（保留兼容性） ===
            df['LONG_SIGNAL_BASIC'] = (
                (df['close'] > df[medium_ma]) &
                (df['MACD'] > df['MACD_SIGNAL']) &
                (df['MACD'].shift(1) <= df['MACD_SIGNAL'].shift(1)) &
                (df['RSI'] < 70)
            ).astype(int)

            df['SHORT_SIGNAL_BASIC'] = (
                (df['close'] < df[medium_ma]) &
                (df['MACD'] < df['MACD_SIGNAL']) &
                (df['MACD'].shift(1) >= df['MACD_SIGNAL'].shift(1)) &
                (df['RSI'] > 30)
            ).astype(int)

            # === 2. 🧠 智能多因子信号系统 ===
            df = self._calculate_multi_factor_signals(df, short_ma, medium_ma)

            # === 3. 🎯 精准入场信号 ===
            df = self._calculate_precision_entry_signals(df)

            # === 4. 🛡️ 风险管理信号 ===
            df = self._calculate_risk_management_signals(df)

            # === 5. 📊 综合评分系统 ===
            df = self._calculate_comprehensive_score(df, short_ma, medium_ma)

            logger.info(f"🚀 使用{short_ma}和{medium_ma}生成激进智能交易信号")
            logger.info("🎯 激进复合交易信号系统完成")
            return df
        except Exception as e:
            logger.error(f"添加复合信号失败: {e}")
            return df

    def _calculate_multi_factor_signals(self, df, short_ma, medium_ma):
        """
        🧠 多因子智能信号系统
        结合趋势、动量、波动率、成交量等多个维度
        """
        logger.info("🧠 计算多因子智能信号...")

        # 初始化信号强度
        df['LONG_STRENGTH'] = 0.0
        df['SHORT_STRENGTH'] = 0.0

        # === 趋势因子 (权重: 30%) ===
        trend_weight = 0.3

        # MA趋势
        if short_ma in df.columns and medium_ma in df.columns:
            ma_trend = np.where(df[short_ma] > df[medium_ma], 1, -1)
            df['LONG_STRENGTH'] += ma_trend * trend_weight * 0.4
            df['SHORT_STRENGTH'] += (-ma_trend) * trend_weight * 0.4

        # ADX趋势强度
        if 'ADX' in df.columns:
            adx_strength = np.clip((df['ADX'] - 20) / 30, 0, 1)  # 标准化到0-1
            trend_direction = np.where(df['PLUS_DI'] > df['MINUS_DI'], 1, -1)
            df['LONG_STRENGTH'] += trend_direction * adx_strength * trend_weight * 0.6
            df['SHORT_STRENGTH'] += (-trend_direction) * adx_strength * trend_weight * 0.6

        # === 动量因子 (权重: 25%) ===
        momentum_weight = 0.25

        # RSI动量
        if 'RSI' in df.columns:
            rsi_momentum = (df['RSI'] - 50) / 50  # 标准化到-1到1
            df['LONG_STRENGTH'] += np.clip(rsi_momentum, 0, 1) * momentum_weight * 0.4
            df['SHORT_STRENGTH'] += np.clip(-rsi_momentum, 0, 1) * momentum_weight * 0.4

        # ROC动量
        if 'ROC' in df.columns:
            roc_momentum = np.clip(df['ROC'] / 10, -1, 1)  # 标准化
            df['LONG_STRENGTH'] += np.clip(roc_momentum, 0, 1) * momentum_weight * 0.6
            df['SHORT_STRENGTH'] += np.clip(-roc_momentum, 0, 1) * momentum_weight * 0.6

        # === 波动率因子 (权重: 20%) ===
        volatility_weight = 0.2

        if 'HV_PERCENTILE' in df.columns:
            # 低波动率有利于趋势延续，高波动率预示反转
            vol_factor = np.where(df['HV_PERCENTILE'] < 30, 0.8,  # 低波动率，趋势信号加强
                        np.where(df['HV_PERCENTILE'] > 70, 0.3, 0.5))  # 高波动率，信号减弱
            df['LONG_STRENGTH'] *= (1 + vol_factor * volatility_weight)
            df['SHORT_STRENGTH'] *= (1 + vol_factor * volatility_weight)

        # === 成交量因子 (权重: 15%) ===
        volume_weight = 0.15

        if 'VOLUME_RATIO' in df.columns:
            # 成交量放大确认信号
            volume_confirmation = np.clip((df['VOLUME_RATIO'] - 1) / 2, 0, 1)
            df['LONG_STRENGTH'] += volume_confirmation * volume_weight
            df['SHORT_STRENGTH'] += volume_confirmation * volume_weight

        # === 市场情绪因子 (权重: 10%) ===
        sentiment_weight = 0.1

        if 'FEAR_GREED_INDEX' in df.columns:
            # 极度恐慌时看多，极度贪婪时看空（逆向思维）
            sentiment_factor = (df['FEAR_GREED_INDEX'] - 50) / 50
            df['LONG_STRENGTH'] += np.clip(-sentiment_factor, 0, 1) * sentiment_weight
            df['SHORT_STRENGTH'] += np.clip(sentiment_factor, 0, 1) * sentiment_weight

        # 生成最终信号
        df['LONG_SIGNAL'] = (df['LONG_STRENGTH'] > 0.6).astype(int)
        df['SHORT_SIGNAL'] = (df['SHORT_STRENGTH'] > 0.6).astype(int)

        return df

    def _calculate_precision_entry_signals(self, df):
        """
        🎯 精准入场信号
        基于价格行为和技术形态的精确入场点
        """
        logger.info("🎯 计算精准入场信号...")

        # === 突破入场信号 ===
        if 'BOLL_UPPER' in df.columns and 'BOLL_LOWER' in df.columns:
            # 布林带突破后回踩确认
            df['BREAKOUT_LONG'] = (
                (df['close'] > df['BOLL_UPPER']) &  # 突破上轨
                (df['close'].shift(1) <= df['BOLL_UPPER'].shift(1)) &  # 前一日未突破
                (df['volume'] > df['volume'].rolling(10).mean() * 1.2)  # 成交量确认
            ).astype(int)

            df['BREAKOUT_SHORT'] = (
                (df['close'] < df['BOLL_LOWER']) &  # 突破下轨
                (df['close'].shift(1) >= df['BOLL_LOWER'].shift(1)) &  # 前一日未突破
                (df['volume'] > df['volume'].rolling(10).mean() * 1.2)  # 成交量确认
            ).astype(int)

        # === 背离入场信号 ===
        if 'RSI' in df.columns and 'MACD' in df.columns:
            # 价格创新高但RSI未创新高（顶背离）
            price_high = df['close'] > df['close'].rolling(10).max().shift(1)
            rsi_high = df['RSI'] < df['RSI'].rolling(10).max().shift(1)
            df['BEARISH_DIVERGENCE'] = (price_high & rsi_high).astype(int)

            # 价格创新低但RSI未创新低（底背离）
            price_low = df['close'] < df['close'].rolling(10).min().shift(1)
            rsi_low = df['RSI'] > df['RSI'].rolling(10).min().shift(1)
            df['BULLISH_DIVERGENCE'] = (price_low & rsi_low).astype(int)

        # === 形态入场信号 ===
        # 锤子线/上吊线识别
        body = abs(df['close'] - df['open'])
        upper_shadow = df['high'] - np.maximum(df['open'], df['close'])
        lower_shadow = np.minimum(df['open'], df['close']) - df['low']

        # 锤子线：下影线长，上影线短，实体小
        df['HAMMER'] = (
            (lower_shadow > body * 2) &  # 下影线是实体的2倍以上
            (upper_shadow < body * 0.5) &  # 上影线很短
            (body < (df['high'] - df['low']) * 0.3)  # 实体小于总区间的30%
        ).astype(int)

        # 上吊线：上影线长，下影线短，实体小
        df['HANGING_MAN'] = (
            (upper_shadow > body * 2) &  # 上影线是实体的2倍以上
            (lower_shadow < body * 0.5) &  # 下影线很短
            (body < (df['high'] - df['low']) * 0.3)  # 实体小于总区间的30%
        ).astype(int)

        return df

    def _calculate_risk_management_signals(self, df):
        """
        🛡️ 风险管理信号系统
        动态止损、仓位管理、风险评估
        """
        logger.info("🛡️ 计算风险管理信号...")

        # === 动态止损系统 ===
        if 'ATR' in df.columns:
            # ATR动态止损
            df['STOP_LOSS_LONG'] = df['close'] - df['ATR'] * 2  # 多头止损位
            df['STOP_LOSS_SHORT'] = df['close'] + df['ATR'] * 2  # 空头止损位

            # 移动止损（追踪止损）
            df['TRAILING_STOP_LONG'] = df['close'].rolling(10).max() - df['ATR'] * 1.5
            df['TRAILING_STOP_SHORT'] = df['close'].rolling(10).min() + df['ATR'] * 1.5

        # === 仓位管理系统 ===
        # 基于波动率的仓位大小
        if 'HV_20' in df.columns:
            # 波动率越高，仓位越小
            target_vol = 15  # 目标年化波动率15%
            df['POSITION_SIZE'] = np.clip(target_vol / df['HV_20'], 0.1, 1.0)

        # === 风险评估 ===
        df['RISK_LEVEL'] = 0

        # 波动率风险
        if 'HV_PERCENTILE' in df.columns:
            df['RISK_LEVEL'] += np.where(df['HV_PERCENTILE'] > 80, 3,
                                np.where(df['HV_PERCENTILE'] > 60, 2, 1))

        # 趋势风险
        if 'ADX' in df.columns:
            df['RISK_LEVEL'] += np.where(df['ADX'] < 20, 2, 0)  # 无趋势时风险增加

        # 背离风险
        if 'BEARISH_DIVERGENCE' in df.columns and 'BULLISH_DIVERGENCE' in df.columns:
            df['RISK_LEVEL'] += df['BEARISH_DIVERGENCE'] + df['BULLISH_DIVERGENCE']

        # 风险等级分类
        df['RISK_CATEGORY'] = np.where(df['RISK_LEVEL'] >= 5, 'HIGH',
                             np.where(df['RISK_LEVEL'] >= 3, 'MEDIUM', 'LOW'))

        # === 资金管理建议 ===
        df['MAX_POSITION'] = np.where(df['RISK_CATEGORY'] == 'HIGH', 0.2,
                            np.where(df['RISK_CATEGORY'] == 'MEDIUM', 0.5, 1.0))

        return df

    def _calculate_comprehensive_score(self, df, short_ma, medium_ma):
        """
        📊 综合评分系统
        整合所有信号生成最终的交易建议
        """
        logger.info("📊 计算综合评分系统...")

        # === 趋势评分 (0-100) ===
        trend_score = 50  # 基础分数

        # MA趋势贡献
        if short_ma in df.columns and medium_ma in df.columns:
            ma_trend = np.where(df[short_ma] > df[medium_ma], 20, -20)
            trend_score += ma_trend

        # MACD趋势贡献
        if 'MACD' in df.columns and 'MACD_SIGNAL' in df.columns:
            macd_trend = np.where(df['MACD'] > df['MACD_SIGNAL'], 15, -15)
            trend_score += macd_trend

        # ADX强度贡献
        if 'ADX' in df.columns:
            adx_bonus = np.clip((df['ADX'] - 20) / 2, 0, 15)
            trend_score += adx_bonus

        df['TREND_SCORE'] = np.clip(trend_score, 0, 100)

        # === 动量评分 (0-100) ===
        momentum_score = 50

        if 'RSI' in df.columns:
            rsi_momentum = (df['RSI'] - 50)  # -50到50
            momentum_score += rsi_momentum * 0.6

        if 'ROC' in df.columns:
            roc_momentum = np.clip(df['ROC'], -25, 25)  # 限制在-25到25
            momentum_score += roc_momentum

        df['MOMENTUM_SCORE'] = np.clip(momentum_score, 0, 100)

        # === 最终交易建议 ===
        df['FINAL_SCORE'] = (df['TREND_SCORE'] * 0.6 + df['MOMENTUM_SCORE'] * 0.4)

        # 交易建议分类
        df['TRADE_RECOMMENDATION'] = np.where(df['FINAL_SCORE'] >= 75, 'STRONG_BUY',
                                    np.where(df['FINAL_SCORE'] >= 60, 'BUY',
                                    np.where(df['FINAL_SCORE'] >= 40, 'HOLD',
                                    np.where(df['FINAL_SCORE'] >= 25, 'SELL', 'STRONG_SELL'))))

        # === 传统信号兼容 ===
        # 保持原有的LONG_SIGNAL和SHORT_SIGNAL，但增强逻辑
        df['LONG_SIGNAL'] = (
            (df['FINAL_SCORE'] >= 65) &  # 综合评分高
            (df['RISK_CATEGORY'] != 'HIGH') &  # 风险不高
            (df['LONG_STRENGTH'] > 0.5)  # 多头强度足够
        ).astype(int)

        df['SHORT_SIGNAL'] = (
            (df['FINAL_SCORE'] <= 35) &  # 综合评分低
            (df['RISK_CATEGORY'] != 'HIGH') &  # 风险不高
            (df['SHORT_STRENGTH'] > 0.5)  # 空头强度足够
        ).astype(int)

        # === 增强的趋势强度 ===
        df['TREND_STRENGTH'] = 0

        # 基础趋势强度
        if short_ma in df.columns and medium_ma in df.columns:
            df.loc[df[short_ma] > df[medium_ma], 'TREND_STRENGTH'] += 1

        if 'MACD' in df.columns:
            df.loc[df['MACD'] > 0, 'TREND_STRENGTH'] += 1

        if 'BOLL_MIDDLE' in df.columns:
            df.loc[df['close'] > df['BOLL_MIDDLE'], 'TREND_STRENGTH'] += 1

        # 高级趋势强度加成
        if 'ADX' in df.columns:
            df.loc[df['ADX'] > 30, 'TREND_STRENGTH'] += 1

        if 'AROON_OSC' in df.columns:
            df.loc[df['AROON_OSC'] > 50, 'TREND_STRENGTH'] += 1

        return df

# 测试函数
def test_ta_calculator():
    """测试技术指标计算功能"""
    print("=" * 50)
    print("技术指标计算模块测试")
    print("=" * 50)
    
    # 创建测试数据
    np.random.seed(42)
    dates = pd.date_range(start='2023-01-01', periods=100, freq='D')
    prices = np.cumsum(np.random.randn(100)) + 100
    df = pd.DataFrame({
        'timestamp': dates,
        'open': prices - np.random.rand(100) * 2,
        'high': prices + np.random.rand(100) * 2,
        'low': prices - np.random.rand(100) * 3,
        'close': prices,
        'volume': np.random.randint(10000, 50000, 100)
    })
    
    print(f"创建测试数据: {len(df)} 条K线")
    print(df.head(3))
    
    # 初始化技术分析器
    analyzer = TechnicalAnalyzer()
    
    # 计算指标
    start_time = time.time()
    df_with_indicators = analyzer.calculate_indicators(df)
    elapsed = time.time() - start_time
    
    if df_with_indicators.empty:
        print("指标计算失败")
        return
    
    print(f"\n指标计算完成，耗时: {elapsed:.4f}秒")
    
    # 添加复合信号
    df_with_signals = analyzer.add_derived_signals(df_with_indicators)
    
    # 显示结果
    print("\n计算结果预览:")
    print(df_with_signals.tail(5))
    
    # 保存结果用于检查
    df_with_signals.to_csv('ta_calculator_test_output.csv', index=False)
    print("测试结果已保存到 ta_calculator_test_output.csv")
    
    # 检查指标列
    indicator_cols = [col for col in df_with_signals.columns if col not in df.columns]
    print(f"\n添加的指标列 ({len(indicator_cols)} 列):")
    print(indicator_cols)
    
    # 检查信号列
    signal_cols = [col for col in df_with_signals.columns if 'SIGNAL' in col or 'CROSS' in col]
    print(f"\n添加的信号列 ({len(signal_cols)} 列):")
    print(signal_cols)

if __name__ == "__main__":
    import time
    # 运行测试
    test_ta_calculator()